#include "bga/graphics/VBORenderer.h"
#include "bga/graphics/VertexBufferObject.h"
#include <iostream>

using namespace std;

#define BUFFER_OFFSET(a) ((char*)NULL + (a))

namespace bga
{

VBORenderer::VBORenderer() : Renderer()
{
}

VBORenderer::~VBORenderer()
{
}

void VBORenderer::render(const Drawable& drawable) const
{
    /// set data (position - normal - color - texCoord)
    drawable.getVBO()->bind();
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));
    if (drawable.getNormalsArraySizeInByte() > 0)
    {
        glEnableClientState(GL_NORMAL_ARRAY);
        glNormalPointer(GL_FLOAT, 0, BUFFER_OFFSET(drawable.getVertexArraySizeInByte()));
    }

    if (drawable.getColorsArraySizeInByte() > 0)
    {
        glEnableClientState(GL_COLOR_ARRAY);
        glColorPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(drawable.getVertexArraySizeInByte() + drawable.getNormalsArraySizeInByte()));
    }

    if (drawable.getTexCoordArraySizeInByte() > 0)
    {
        glClientActiveTexture(GL_TEXTURE0);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glTexCoordPointer(drawable.getNbTexCoordPerElement(), GL_FLOAT, 0, BUFFER_OFFSET(drawable.getVertexArraySizeInByte() + drawable.getNormalsArraySizeInByte() + drawable.getColorsArraySizeInByte()));
    }

    drawable.getEBO()->bind();
    glDrawElements(drawable.getPrimitive(), drawable.getIndexArraySize(), GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));

    if (drawable.getTexCoordArraySizeInByte() > 0)
    {
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    }
    if (drawable.getColorsArraySizeInByte() > 0)
    {
        glDisableClientState(GL_COLOR_ARRAY);
    }
    if (drawable.getNormalsArraySizeInByte() > 0)
    {
        glDisableClientState(GL_NORMAL_ARRAY);
    }
    glDisableClientState(GL_VERTEX_ARRAY);
}

}
